<template>
  <div class="app-container">
    <div class="map-wrapper">
      <div id="map-container"></div>
      <div class="control-panel">
        <div class="panel-header">
          <h3>长虹乡地图导览</h3>
          <p>探索长虹乡的景点、餐饮与住宿</p>
        </div>
        <div class="panel-body">
          <div class="control-group">
            <h4>图层筛选</h4>
            <div class="layer-buttons">
              <el-button
                plain
                :type="activeLayer === 'all' ? 'primary' : ''"
                @click="setActiveLayer('all')">全部</el-button>
              <el-button
                plain
                :type="activeLayer === 'scenic' ? 'primary' : ''"
                @click="setActiveLayer('scenic')">景区</el-button>
              <el-button
                plain
                :type="activeLayer === 'food' ? 'primary' : ''"
                @click="setActiveLayer('food')">餐饮</el-button>
              <el-button
                plain
                :type="activeLayer === 'hotel' ? 'primary' : ''"
                @click="setActiveLayer('hotel')">住宿</el-button>
            </div>
          </div>

          <div class="control-group route-control">
            <h4>路线规划</h4>
            <el-select
              v-model="selectedStart"
              placeholder="选择起点"
              filterable
              clearable
              @change="handleStartChange">
              <el-option
                v-for="item in allMarkers"
                :key="item.id"
                :label="item.name"
                :value="item.id">
                <span>{{ item.name }}</span>
                <span class="option-type">{{ getTypeName(item.type) }}</span>
              </el-option>
            </el-select>
            <el-select
              v-model="selectedEnd"
              placeholder="选择终点"
              filterable
              clearable
              @change="handleEndChange">
              <el-option
                v-for="item in allMarkers"
                :key="item.id"
                :label="item.name"
                :value="item.id">
                <span>{{ item.name }}</span>
                <span class="option-type">{{ getTypeName(item.type) }}</span>
              </el-option>
            </el-select>
            <div class="route-actions">
              <el-button
                type="primary"
                @click="startRoutePlanning"
                :disabled="!selectedStart || !selectedEnd">
                <i class="el-icon-guide"></i> 开始规划
              </el-button>
              <el-button
                @click="clearRoute"
                :disabled="!currentRoute">
                <i class="el-icon-delete"></i> 清除
              </el-button>
            </div>
          </div>

          <div class="route-info" v-if="routeInfo">
            <div class="info-summary">
              <div class="info-item">
                <span class="label">距离:</span>
                <span class="value">{{ routeInfo.distance }} km</span>
              </div>
              <div class="info-item">
                <span class="label">时间:</span>
                <span class="value">{{ routeInfo.time }} 分钟</span>
              </div>
            </div>
            <div class="steps-container">
              <div class="step-item" v-for="(step, index) in routeInfo.steps" :key="index">
                <div class="step-index">{{ index + 1 }}</div>
                <div class="step-content">{{ step.instruction }}</div>
                <div class="step-distance">{{ step.distance }}米</div>
              </div>
            </div>
          </div>
        </div>
        <el-button class="reset-btn" type="primary" circle @click="centerMap">
          <i class="el-icon-aim"></i>
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import { getMapMarkers } from '@/api/system/map'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faUmbrellaBeach, faUtensils, faHotel } from '@fortawesome/free-solid-svg-icons'

export default {
  name: 'ChanghongMap',
  components: {
    FontAwesomeIcon
  },
  data() {
    return {
      map: null,
      markers: [],
      allMarkers: [],
      mapCenter: [118.245678, 29.294567],
      activeLayer: 'all',
      infoWindow: null,
      markerClusterer: null,
      mapBounds: null,
      selectedStart: null,
      selectedEnd: null,
      currentRoute: null,
      routeInfo: null,
      driving: null,
      startMarker: null,
      endMarker: null,
      iconConfig: {
        scenic: {
          icon: faUmbrellaBeach,
          color: '#67C23A',
          bgColor: 'rgba(103, 194, 58, 0.2)'
        },
        food: {
          icon: faUtensils,
          color: '#E6A23C',
          bgColor: 'rgba(230, 162, 60, 0.2)'
        },
        hotel: {
          icon: faHotel,
          color: '#409EFF',
          bgColor: 'rgba(64, 158, 255, 0.2)'
        }
      }
    }
  },
  mounted() {
    window._AMapSecurityConfig = {
      securityJsCode: 'dce306f9fc4a19f5991eb22dd4653d59'
    }
    this.initMap()
  },
  methods: {
    async initMap() {
      try {
        await AMapLoader.load({
          key: 'd4499fcf139b99718e1946bd5f16ff99',
          version: '2.0',
          plugins: [
            'AMap.ToolBar',
            'AMap.Scale',
            'AMap.MarkerClusterer',
            'AMap.InfoWindow',
            'AMap.Driving'
          ],
        })

        this.map = new AMap.Map('map-container', {
          viewMode: '2D',
          zoom: 13,
          center: this.mapCenter,
          mapStyle: 'amap://styles/fresh',
          showBuildingBlock: true
        });

        this.driving = new AMap.Driving({
          map: this.map,
          policy: AMap.DrivingPolicy.LEAST_TIME,
          panel: null
        });

        this.map.addControl(new AMap.ToolBar({
          position: { right: '20px', top: '20px' }
        }));

        this.map.addControl(new AMap.Scale({
          position: 'LB'
        }));

        this.infoWindow = new AMap.InfoWindow({
          offset: new AMap.Pixel(0, -30),
          closeWhenClickMap: true
        });

        this.loadMarkers();
      } catch (e) {
        console.error('地图加载失败:', e);
        this.$message.error('地图加载失败，请稍后再试');
      }
    },

    createCustomIcon(type) {
      const config = this.iconConfig[type] || this.iconConfig.scenic;
      const div = document.createElement('div');

      div.innerHTML = `
        <div style="
          width: 24px;
          height: 24px;
          border-radius: 50%;
          background: ${config.bgColor};
          display: flex;
          align-items: center;
          justify-content: center;
          border: 1px solid ${config.color};
        ">
          <svg
            width="12"
            height="12"
            fill="${config.color}"
            viewBox="0 0 512 512"
          >
            <path d="${config.icon.icon[4]}"/>
          </svg>
        </div>
      `;

      return div;
    },

    async loadMarkers() {
      try {
        const response = await getMapMarkers();

        const validData = response.data.map(item => ({
          ...item,
          longitude: Number(item.longitude),
          latitude: Number(item.latitude)
        })).filter(item =>
          !isNaN(item.longitude) &&
          !isNaN(item.latitude)
        );

        if (validData.length === 0) {
          this.$message.warning('未找到有效的坐标数据');
          return;
        }

        this.allMarkers = validData;

        const lngs = validData.map(item => item.longitude);
        const lats = validData.map(item => item.latitude);
        const minLng = Math.min(...lngs);
        const maxLng = Math.max(...lngs);
        const minLat = Math.min(...lats);
        const maxLat = Math.max(...lats);

        this.mapCenter = [(minLng + maxLng) / 2, (minLat + maxLat) / 2];
        this.centerMap();

        this.createMarkers(validData);
      } catch (error) {
        console.error('加载标记点失败:', error);
        this.$message.error('加载标记点数据失败');
      }
    },

    createMarkers(markersData) {
      if (this.markers.length > 0) {
        this.map.remove(this.markers);
        this.markers = [];
      }

      markersData.forEach(item => {
        const marker = new AMap.Marker({
          position: new AMap.LngLat(item.longitude, item.latitude),
          title: item.name,
          content: this.createCustomIcon(item.type).innerHTML,
          extData: item,
          offset: new AMap.Pixel(-12, -12),
          zIndex: 10
        });

        marker.on('click', (e) => {
          this.showMarkerInfo(e.target.getExtData());
        });

        this.markers.push(marker);
      });

      this.map.add(this.markers);

      if (this.markerClusterer) {
        this.markerClusterer.setMap(null);
      }
      this.markerClusterer = new AMap.MarkerClusterer(this.map, this.markers, {
        gridSize: 60,
        renderClusterMarker: this.renderClusterMarker
      });

      this.filterMarkersByLayer();
    },

    renderClusterMarker(context) {
      const count = context.count;
      const size = Math.min(40 + Math.sqrt(count) * 4, 60);
      const div = document.createElement('div');

      div.innerHTML = `
        <div style="
          width: ${size}px;
          height: ${size}px;
          border-radius: 50%;
          background: rgba(64, 158, 255, 0.2);
          border: 2px solid rgba(64, 158, 255, 0.8);
          display: flex;
          align-items: center;
          justify-content: center;
          color: #fff;
          font-weight: bold;
          font-size: ${Math.min(size/3, 16)}px;
        ">
          ${count}
        </div>
      `;

      context.marker.setOffset(new AMap.Pixel(-size/2, -size/2));
      context.marker.setContent(div.innerHTML);
    },

    showMarkerInfo(data) {
      const config = this.iconConfig[data.type] || this.iconConfig.scenic;

      // 处理图片URL
      let imageUrls = [];
      if (data.imageUrl) {
        try {
          if (data.imageUrl.startsWith('[')) {
            const parsed = JSON.parse(data.imageUrl);
            if (Array.isArray(parsed)) {
              imageUrls = parsed.map(url => this.processImageUrl(url));
            } else {
              imageUrls = [this.processImageUrl(data.imageUrl)];
            }
          } else {
            imageUrls = [this.processImageUrl(data.imageUrl)];
          }
        } catch (e) {
          imageUrls = [this.processImageUrl(data.imageUrl)];
        }
      }

      // 创建图片容器
      const imgContainer = document.createElement('div');
      imgContainer.style.width = '100%';
      imgContainer.style.height = '140px';
      imgContainer.style.position = 'relative';
      imgContainer.style.overflow = 'hidden';
      imgContainer.style.borderRadius = '4px';
      imgContainer.style.marginTop = '10px';

      if (imageUrls.length > 0) {
        const carousel = document.createElement('div');
        carousel.style.width = '100%';
        carousel.style.height = '100%';
        carousel.style.display = 'flex';
        carousel.style.overflowX = 'auto';
        carousel.style.scrollSnapType = 'x mandatory';

        imageUrls.forEach(url => {
          if (!url) return;

          const imgDiv = document.createElement('div');
          imgDiv.style.minWidth = '100%';
          imgDiv.style.scrollSnapAlign = 'start';
          imgDiv.style.position = 'relative';

          const img = document.createElement('img');
          const fullUrl = url.startsWith('http') ? url : `${window.location.origin}${url}`;
          img.src = fullUrl;
          img.style.width = '100%';
          img.style.height = '100%';
          img.style.objectFit = 'cover';

          img.onerror = function(e) {
            imgDiv.style.display = 'none';
          };

          imgDiv.appendChild(img);
          carousel.appendChild(imgDiv);
        });

        imgContainer.appendChild(carousel);
      }

      // 创建信息窗口内容
      const content = document.createElement('div');
      content.style.minWidth = '250px';
      content.style.padding = '12px';

      const header = document.createElement('div');
      header.style.display = 'flex';
      header.style.alignItems = 'center';
      header.style.marginBottom = '8px';

      const iconDiv = document.createElement('div');
      iconDiv.style.width = '24px';
      iconDiv.style.height = '24px';
      iconDiv.style.borderRadius = '50%';
      iconDiv.style.background = config.bgColor;
      iconDiv.style.display = 'flex';
      iconDiv.style.alignItems = 'center';
      iconDiv.style.justifyContent = 'center';
      iconDiv.style.marginRight = '8px';
      iconDiv.style.border = `1px solid ${config.color}`;

      const iconSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
      iconSvg.setAttribute('width', '12');
      iconSvg.setAttribute('height', '12');
      iconSvg.setAttribute('fill', config.color);
      iconSvg.setAttribute('viewBox', '0 0 512 512');

      const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
      path.setAttribute('d', config.icon.icon[4]);
      iconSvg.appendChild(path);
      iconDiv.appendChild(iconSvg);

      const title = document.createElement('h4');
      title.style.margin = '0';
      title.style.color = '#333';
      title.style.fontSize = '16px';
      title.textContent = data.name;

      header.appendChild(iconDiv);
      header.appendChild(title);

      const type = document.createElement('p');
      type.style.margin = '4px 0';
      type.style.fontSize = '13px';
      type.style.color = '#666';
      type.innerHTML = `<span style="color: ${config.color}">${this.getTypeName(data.type)}</span>`;

      content.appendChild(header);
      content.appendChild(type);

      if (data.description) {
        const desc = document.createElement('p');
        desc.style.margin = '8px 0 0 0';
        desc.style.fontSize = '13px';
        desc.style.color = '#666';
        desc.textContent = data.description;
        content.appendChild(desc);
      }

      // 如果有图片，添加到内容中
      if (imageUrls.length > 0 && imgContainer.children.length > 0) {
        content.appendChild(imgContainer);
      }

      this.infoWindow.setContent(content);
      this.infoWindow.open(this.map, [data.longitude, data.latitude]);
    },
    processImageUrl(url) {
      if (!url) return null;

      let cleanedUrl = url;
      try {
        if (url.trim().startsWith('[') || url.trim().startsWith('"')) {
          cleanedUrl = JSON.parse(url);
          if (Array.isArray(cleanedUrl)) {
            cleanedUrl = cleanedUrl[0];
          }
        }
      } catch (e) {
        cleanedUrl = url;
      }

      cleanedUrl = String(cleanedUrl)
        .replace(/\\"/g, '')
        .replace(/^"+|"+$/g, '')
        .trim();

      if (cleanedUrl.includes('您的域名或IP:端口')) {
        cleanedUrl = cleanedUrl.replace('您的域名或IP:端口', window.location.host+':8080');
      }

      if (cleanedUrl.startsWith('http://') || cleanedUrl.startsWith('https://')) {
        return cleanedUrl;
      }

      if (cleanedUrl.startsWith('/')) {
        return window.location.origin + cleanedUrl;
      }

      if (cleanedUrl.startsWith('profile/')) {
        return window.location.origin + '/' + cleanedUrl;
      }

      return cleanedUrl;
    },

    startRoutePlanning() {
      if (!this.selectedStart || !this.selectedEnd) {
        this.$message.warning('请选择起点和终点');
        return;
      }

      const startPoint = this.allMarkers.find(item => item.id === this.selectedStart);
      const endPoint = this.allMarkers.find(item => item.id === this.selectedEnd);

      if (!startPoint || !endPoint) {
        this.$message.error('选择的起点或终点无效');
        return;
      }

      this.clearRoute();
      this.createRouteMarkers(startPoint, endPoint);
      this.searchRoute(startPoint, endPoint);
    },

    createRouteMarkers(startPoint, endPoint) {
      if (this.startMarker) this.map.remove(this.startMarker);
      if (this.endMarker) this.map.remove(this.endMarker);

      this.startMarker = new AMap.Marker({
        position: new AMap.LngLat(startPoint.longitude, startPoint.latitude),
        icon: new AMap.Icon({
          size: new AMap.Size(24, 24),
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/start.png',
          imageSize: new AMap.Size(24, 24)
        }),
        offset: new AMap.Pixel(-12, -24),
        zIndex: 100
      });
      this.map.add(this.startMarker);

      this.endMarker = new AMap.Marker({
        position: new AMap.LngLat(endPoint.longitude, endPoint.latitude),
        icon: new AMap.Icon({
          size: new AMap.Size(24, 24),
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/end.png',
          imageSize: new AMap.Size(24, 24)
        }),
        offset: new AMap.Pixel(-12, -24),
        zIndex: 100
      });
      this.map.add(this.endMarker);
    },

    searchRoute(startPoint, endPoint) {
      const start = new AMap.LngLat(Number(startPoint.longitude), Number(startPoint.latitude));
      const end = new AMap.LngLat(Number(endPoint.longitude), Number(endPoint.latitude));

      this.driving.search(
        start,
        end,
        { policy: AMap.DrivingPolicy.LEAST_TIME },
        (status, result) => {
          if (status === 'complete') {
            this.routeSuccess(result);
          } else {
            this.routeError(result);
          }
        }
      );
    },

    routeSuccess(result) {
      this.currentRoute = result.routes[0];
      const distance = (this.currentRoute.distance / 1000).toFixed(1);
      const time = Math.round(this.currentRoute.time / 60);

      const steps = [];
      this.currentRoute.steps.forEach(step => {
        const instruction = step.instruction.replace(/<[^>]+>/g, '');
        steps.push({
          instruction: instruction,
          distance: step.distance
        });
      });

      this.routeInfo = {
        distance: distance,
        time: time,
        steps: steps
      };

      this.adjustMapViewToRoute();
    },

    adjustMapViewToRoute() {
      if (this.currentRoute && this.currentRoute.path) {
        this.map.setFitView(this.currentRoute.path, {
          padding: [20, 20, 20, 320],
          animate: true
        });
      }
    },

    routeError(result) {
      console.error('路线规划失败:', result);
      this.$message.error('路线规划失败: ' + (result.info || '未知错误'));
    },

    clearRoute() {
      if (this.currentRoute) {
        this.driving.clear();
        this.currentRoute = null;
        this.routeInfo = null;
      }
      if (this.startMarker) {
        this.map.remove(this.startMarker);
        this.startMarker = null;
      }
      if (this.endMarker) {
        this.map.remove(this.endMarker);
        this.endMarker = null;
      }
    },

    handleStartChange(value) {
      if (value && this.selectedEnd && value === this.selectedEnd) {
        this.$message.warning('起点和终点不能相同');
        this.selectedStart = null;
      }
    },

    handleEndChange(value) {
      if (value && this.selectedStart && value === this.selectedStart) {
        this.$message.warning('终点和起点不能相同');
        this.selectedEnd = null;
      }
    },

    getTypeName(type) {
      const typeNames = {
        scenic: '景区',
        food: '餐饮',
        hotel: '住宿'
      };
      return typeNames[type] || type;
    },

    setActiveLayer(layer) {
      this.activeLayer = layer;
      this.filterMarkersByLayer();
    },

    filterMarkersByLayer() {
      this.markers.forEach(marker => {
        const data = marker.getExtData();
        marker[this.activeLayer === 'all' || data.type === this.activeLayer ? 'show' : 'hide']();
      });

      if (this.markerClusterer) {
        this.markerClusterer.setMap(null);
        this.markerClusterer = new AMap.MarkerClusterer(this.map, this.markers, {
          gridSize: 60,
          renderClusterMarker: this.renderClusterMarker
        });
      }
    },

    centerMap() {
      this.map.setZoomAndCenter(13, this.mapCenter);
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 0;
  height: 100vh;
  background: #f5f7fa;
}

.map-wrapper {
  position: relative;
  height: 100%;
  width: 100%;
}

#map-container {
  height: 100%;
  width: 100%;
}

.control-panel {
  position: absolute;
  right: 20px;
  top: 20px;
  width: 320px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 10;
  overflow: hidden;
}

.panel-header {
  padding: 16px;
  background: #409EFF;
  color: #fff;
}

.panel-header h3 {
  margin: 0 0 4px 0;
  font-size: 18px;
  font-weight: 500;
}

.panel-header p {
  margin: 0;
  font-size: 12px;
  opacity: 0.8;
}

.panel-body {
  padding: 16px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}

.control-group {
  margin-bottom: 20px;
}

.control-group h4 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #606266;
  font-weight: normal;
}

.layer-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.layer-buttons .el-button {
  flex: 1;
  min-width: 60px;
  padding: 8px 12px;
}

.route-control .el-select {
  width: 100%;
  margin-bottom: 12px;
}

.route-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.route-actions .el-button {
  flex: 1;
}

.route-info {
  margin-top: 16px;
  border-top: 1px solid #ebeef5;
  padding-top: 16px;
}

.info-summary {
  display: flex;
  gap: 16px;
  margin-bottom: 12px;
}

.info-item {
  font-size: 13px;
}

.info-item .label {
  color: #909399;
}

.info-item .value {
  color: #303133;
  font-weight: bold;
}

.steps-container {
  max-height: 300px;
  overflow-y: auto;
}

.step-item {
  display: flex;
  align-items: flex-start;
  padding: 8px 0;
  border-bottom: 1px dashed #ebeef5;
}

.step-index {
  width: 18px;
  height: 18px;
  line-height: 18px;
  text-align: center;
  background: #409EFF;
  color: #fff;
  border-radius: 50%;
  margin-right: 8px;
  font-size: 12px;
  flex-shrink: 0;
  margin-top: 2px;
}

.step-content {
  flex: 1;
  font-size: 13px;
  color: #606266;
  line-height: 1.5;
}

.step-distance {
  margin-left: 8px;
  color: #909399;
  font-size: 12px;
  flex-shrink: 0;
}

.reset-btn {
  position: absolute;
  right: 20px;
  bottom: 20px;
  z-index: 10;
  width: 40px;
  height: 40px;
  padding: 0;
}

.option-type {
  float: right;
  color: #909399;
  font-size: 12px;
}

@media (max-width: 768px) {
  .control-panel {
    position: static;
    width: 100%;
    border-radius: 0;
    box-shadow: none;
  }

  .panel-body {
    max-height: none;
  }

  .reset-btn {
    right: 10px;
    bottom: 10px;
  }
}
/* 路线规划线条样式 */
.amap-driving-route {
  stroke-width: 4px;
  stroke: #409EFF;
  stroke-opacity: 0.8;
  animation: routeFlow 2s infinite linear;
}

@keyframes routeFlow {
  from {
    stroke-dashoffset: 0;
  }
  to {
    stroke-dashoffset: 20;
  }
}
</style>
